home *** CD-ROM | disk | FTP | other *** search
- /* support for environment variables */
-
- #include <stdio.h>
- #include <ctype.h>
-
- #include "global.h"
- #include "environ.h"
-
- extern char startup[],on_exit[],userfile[],hosts[],fingerpath[],mailspool[],
- mailqdir[],routeqdir[],alias[],tmpdir[];
-
- /* default names and values for environment vars */
-
- char STARTUP[] = "NETSTART"; /* Initialization file */
- char ONEXIT[] = "NETEXIT"; /* Initialization file */
- char USERFILE[] = "NETUSERS"; /* Authorized FTP users and passwords */
- char HOSTS[] = "NETHOSTS"; /* Network host table */
- char FINGERPATH[] = "NETFINGER"; /* Finger file path */
- char MAILSPOOL[] = "NETMAILS"; /* Incoming mail */
- char MAILQDIR[] = "NETMAILQ"; /* Outgoing mail spool */
- char ROUTEQDIR[] = "NETROUTEQ"; /* queue for router */
- char ALIAS[] = "NETALIAS"; /* the alias file */
- #ifdef ATARI_ST
- char TIMEZONE[] = "TIMEZONE"; /* local time zone */
- char TMPDIR[] = "TMPDIR"; /* temp files directory */
- char ATARI_STYLE[]= "ENVSTYLE"; /* Environment style DOS/Atari */
- #endif
- #ifdef MSDOS
- char TIMEZONE[] = "TZ"; /* local time zone */
- #endif
-
- struct env_default env_defs[] = {
- STARTUP, startup, /* Initialization file */
- ONEXIT, on_exit, /* Termination file */
- USERFILE, userfile, /* Authorized FTP users and passwords */
- HOSTS, hosts, /* Network host table */
- FINGERPATH, fingerpath, /* Finger file path */
- MAILSPOOL, mailspool, /* Incoming mail */
- MAILQDIR, mailqdir, /* Outgoing mail spool */
- ROUTEQDIR, routeqdir, /* queue for router */
- ALIAS, alias, /* the alias file */
- #ifdef ATARI_ST
- TIMEZONE, "GMT:0", /* default local timezone */
- TMPDIR, tmpdir, /* temp files directory */
- #endif
- #ifdef MSDOS
- TIMEZONE, "GMT0", /* default local timezone */
- #endif
- NULLCHAR, NULLCHAR
- };
-
- struct env_var *the_env = NULLENV;
- char **env_envp = NULLCHRP; /* stores last envp from make_env */
- static char **env_wenvp; /* working copy for fill_env */
- char *env_env = NULLCHAR; /* stores last env from make_env */
- static char *env_wenv; /* working copy for fill_env */
-
- #ifdef ATARI_ST
- static int atari_style = 1; /* Atari-style (not MSDOS) environment */
- #endif
-
- extern char nospace[]; /* No space!! message */
-
- /* lookup/create an environment-variable node */
- static struct env_var *
- env_node (name,creat)
- char *name;
- int creat;
- {
- register struct env_var **env_pp = &the_env;
- register char *p,*q;
- int r;
-
- while (*env_pp != NULLENV) {
- p = (*env_pp)->name; /* compare current name */
- q = name; /* with searched name */
-
- while (*p == *q) {
- if (*p == '\0' || *q == '='){
- break;
- }
- p++;
- q++;
- }
-
- if (*q == '=') /* test end-result */
- r = -*p;
- else
- r = *q - *p;
-
- if (!r) /* found it? */
- return *env_pp; /* then return the node */
-
- if (r < 0) /* smaller? */
- env_pp = &(*env_pp)->left; /* go left */
- else
- env_pp = &(*env_pp)->right; /* else go right */
- }
-
- /* not found, create a new node? */
-
- if (!creat)
- return NULLENV;
-
- for (p = name; *p != '\0' && *p != '='; p++) /* find namelength */
- ;
-
- if ((*env_pp = (struct env_var *)
- calloc(1,sizeof(struct env_var) + p - name)) == NULLENV){
- printf(nospace);
- return NULLENV;
- }
-
- memcpy((*env_pp)->name,name,p - name); /* copy name */
-
- return *env_pp; /* return created node */
- }
-
- /* read the value of an environment variable (of the local copy, that is) */
- /* it returns a pointer to the actual value, so you can do multiple calls */
- /* to getenv, and save the resulting pointers. (the Aztec getenv returns */
- /* a pointer to a static area overwritten by each call, UNIX(tm) doesn't) */
- char *getenv (name)
- #if (defined(MSC) || defined(__TURBOC__))
- const /* agree with stdlib.h declaration */
- #endif
- char *name;
- {
- register struct env_var *env_p;
-
- if ((env_p = env_node(name,0)) == NULLENV)
- return NULLCHAR; /* no space, does not exist */
-
- return env_p->value; /* return value or NULL */
- }
-
- /* read the value of an environment variable (of the local copy, that is) */
- /* same as getenv(), but return "" instead of NULL when it does not exist */
- char *getnenv (name)
- char *name;
- {
- char *rv;
-
- if ((rv = getenv(name)) == NULL)
- rv = ""; /* NULL replaced by "" */
-
- return rv;
- }
-
- /* set the value of an environment variable */
- struct env_var *
- setenv (name,value)
- char *name;
- char *value;
- {
- register struct env_var *env_p;
-
- if ((env_p = env_node(name,1)) == NULLENV)
- return NULLENV; /* no space */
-
- if (env_p->value_alloc)
- free(env_p->value);
-
- env_p->value = value;
- return env_p;
- }
-
- /* read the supplied environment at program startup */
- void
- readenv (envp)
- char *envp[];
- {
- register int i;
- register char *p;
- char *name,*value;
- struct env_default *defs;
-
- /* read the fixed default values */
-
- for (defs = env_defs; defs->name != NULLCHAR; defs++)
- setenv(defs->name,defs->value);
-
- /* then, override these with environment values */
-
- #if (defined(MSDOS) && !defined(MSC) && !defined(__TURBOC__))
- /* special treatment for Aztec C which does not pass envp to main() */
- {
- extern short _PSP; /* segment of the PSP */
- char *buf[2];
- char far *fp;
-
- if ((buf[1] = malloc(512)) == NULLCHAR) /* allocate a near buf */
- return;
-
- /* get far ptr to env, whose SEG is in 22'th WORD of the PSP */
- fp = (char far *) ((long) (((short far *) ((long) _PSP << 16))[22]) << 16);
-
- while (*fp != '\0'){ /* scan the env */
- p = buf[1];
- while ((*p++ = *fp++) != '\0') /* copy a NAME=value line */
- ; /* to a near buffer (8086...) */
-
- if (isalpha(*buf[1])) /* is it a valid name? */
- dosetenv(2,buf); /* than fake a setenv command */
- }
-
- free(buf[1]);
- }
- #else
- /* all others use the third arg of main() (envp) */
-
- if (envp == NULLCHRP) /* no environment? */
- return; /* nothing to read... */
-
- for (i = 0; (name = envp[i]) != NULLCHAR; i++) {
- value = NULLCHAR;
- for (p = name; *p != '\0'; p++)
- if (*p == '=') {
- #ifdef ATARI_ST
- if (p[1] != '\0') /* when no \0, it is MSDOS-style */
- atari_style = 0;
- #endif
- value = p + 1; /* MSDOS-style has value after = */
- break;
- }
-
- #ifdef ATARI_ST
- if (atari_style) /* Atari-style has separate value */
- if ((value = envp[++i]) == NULLCHAR) /* get the value */
- i--; /* protect against passing end of env */
-
- if (!strncmp(name,"ARGV",p - name))
- continue; /* ignore ARGV= var on Atari */
- #endif
- #ifdef MSDOS
- if (!isalpha(name[0])) /* ignore funny var names */
- continue;
- #endif
-
- if (value != NULLCHAR)
- setenv(name,value);
- }
- #endif
-
- #ifdef ATARI_ST
- if (atari_style)
- setenv(ATARI_STYLE,"1"); /* define atari-style env */
- #endif
- }
-
- /* get the number of items in the currently stored environment */
- static unsigned
- env_count(env_v)
- register struct env_var *env_v;
- {
- if (env_v == NULLENV) /* end of tree? */
- return 0;
-
- return (env_count(env_v->left) + /* return sum of all nodes */
- ((env_v->value != NULLCHAR)? 1 : 0) +
- env_count(env_v->right));
- }
-
- /* get the size of the currently stored environment */
- static unsigned
- env_size(env_v)
- register struct env_var *env_v;
- {
- if (env_v == NULLENV) /* end of tree? */
- return 0;
-
- return (env_size(env_v->left) + /* return sum of all nodes */
- ((env_v->value != NULLCHAR)?
- (strlen(env_v->name) + strlen(env_v->value) + 2)
- #ifdef ATARI_ST
- + atari_style /* Atari-style requires extra byte */
- #endif
- :
- 0) +
- env_size(env_v->right));
- }
-
- /* fill a buffer with the environment vars */
- static
- fill_env(env_v)
- register struct env_var *env_v;
- {
- register char *p;
-
- if (env_v != NULLENV) { /* not end of tree? */
- fill_env(env_v->left);
-
- if (env_v->value != NULLCHAR){ /* not unset? */
- *env_wenvp++ = env_wenv; /* put pointer in envp array */
-
- for (p = env_v->name; *p != '\0'; ) /* store name */
- *env_wenv++ = *p++;
-
- *env_wenv++ = '=';
- #ifdef ATARI_ST
- if (atari_style)
- env_wenv++; /* put that extra \0 */
- #endif
-
- for (p = env_v->value; *p != '\0'; ) /* store value */
- *env_wenv++ = *p++;
-
- env_wenv++; /* term by \0 */
- }
-
- fill_env(env_v->right);
- }
- }
-
- /* allocate and fill a contiguous buffer with the environment vars */
- char **
- make_env()
- {
- #ifdef ATARI_ST
- atari_style = atoi(getnenv(ATARI_STYLE)) & 1; /* set env style */
- #endif
-
- if ((env_env = calloc(1,env_size(the_env) + 1 + 15)) == NULLCHAR) {
- printf("cannot alloc mem for env\n");
- return NULLCHRP;
- }
-
- if ((env_envp = (char **) calloc(sizeof(char *),env_count(the_env) + 1)) == NULLCHRP) {
- printf("cannot alloc mem for envp\n");
- return NULLCHRP;
- }
-
- #ifdef MSDOS
- /* MS-DOS likes to have the environment on a paragraph boundary, */
- /* so that it can be referenced using only a segment address, */
- /* and always offset 0. yuck. */
- #ifdef LARGEDATA
- env_wenv = (char *) (((((unsigned) env_env + 0x0f) >> 4) + ((unsigned long) env_env >> 16)) << 16);
- #else
- env_wenv = (char *) (((unsigned) env_env + 0x0f) & ~0x0f);
- #endif
- #else
- env_wenv = env_env;
- #endif
- env_wenvp = env_envp;
-
- fill_env(the_env); /* recursively add all vars */
-
- return env_envp;
- }
-
- /* free the memory asociated with the last make_env call */
- void
- free_env ()
-
- {
- if (env_envp != NULLCHRP)
- free(env_envp);
-
- if (env_env != NULLCHAR)
- free(env_env);
-
- env_envp = NULLCHRP;
- env_env = NULLCHAR;
- }
-
- /* dump contents of environment */
- static int
- doenvdump(env_v)
- register struct env_var *env_v;
- {
- register char *p;
-
- if (env_v != NULLENV) { /* not end of tree? */
- doenvdump(env_v->left);
-
- if (env_v->value != NULLCHAR) {
- printf("%s=",env_v->name);
-
- for (p = env_v->value; *p != '\0'; p++) {
- if (*p < ' ') { /* a control char? */
- putchar('^'); /* show as ^char */
- putchar(*p + 64);
- } else
- putchar(*p);
- }
-
- putchar('\n');
- }
-
- doenvdump(env_v->right);
- }
-
- return 0;
- }
-
- /* handle the "setenv" command */
- int
- dosetenv(argc,argv)
- int argc;
- char *argv[];
- {
- char *value,*avalue;
- register struct env_var *env_p;
- register char *p;
- int l;
-
- if (argc < 2) /* only "setenv" typed */
- return doenvdump(the_env);
-
- for (p = argv[1]; *p != '\0'; p++) {
- if (*p == '=')
- break;
-
- *p = toupper(*p); /* upcase the name */
- }
-
- if (*p != '\0') /* found an =? */
- value = p + 1; /* then value is right after it */
- else
- value = argv[2]; /* value is next arg, if provided */
- /* if no value provided, unset it */
-
- /* allocate copy of value */
-
- if (value != NULLCHAR) {
- if ((avalue = malloc(l = strlen(value) + 1)) == NULLCHAR) {
- printf(nospace);
- return -1;
- }
-
- memcpy(avalue,value,l);
- } else {
- avalue = value;
- }
-
- if ((env_p = setenv(argv[1],avalue)) == NULLENV)
- return -1; /* no space */
-
- if (value != NULLCHAR)
- env_p->value_alloc = 1; /* remember value is allocated */
- else
- env_p->value_alloc = 0; /* NULL value is not allocated */
-
- return 0;
- }
-
-